package group.sicher.core.utils;

import com.google.common.collect.Lists;
import group.sicher.core.log.LogManagerUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;

import java.security.InvalidParameterException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * description:
 * author:aron
 * date:2019/3/29
 */
public class SicherDateUtils {

    public static final String YYYY_MM_dd_HHmmss = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_dd_HH_mm = "yyyy-MM-dd-HH-mm";
    public static final String YYYY_MM_dd_HHmm = "yyyy-MM-dd HH:mm";
    public static final String YYYY_MM_dd_HH = "yyyy-MM-dd HH";
    public static final String YYYY_MM_dd = "yyyy-MM-dd";
    public static final String YYYY$_MM$_dd = "yyyy/MM/dd";
    public static final String YYYYMMddHHmmss = "yyyyMMdd HH:mm:ss";
    public static final String YYYYMMdd_HHmmss = "yyyyMMdd-HHmmss";
    public static final String YYYYMMddHHmm = "yyyyMMdd HH:mm";
    public static final String YYYYMMddHH = "yyyyMMdd HH";
    public static final String YYYYMMdd = "yyyyMMdd";
    public static final String YYYY$MM$ddHHmmss = "yyyy.MM.dd HH:mm:ss";
    public static final String YYYY$MM$ddHHmm = "yyyy.MM.dd HH:mm";
    public static final String YYYY$MM$ddHH = "yyyy.MM.dd HH";
    public static final String YYYY$MM$dd = "yyyy.MM.dd";
    public static final String YYYY_MM = "YYYY-MM";

    private static Logger logger = LogManagerUtils.getLogger(SicherDateUtils.class);

    /**
     * 获取当前的时间
     *
     * @return
     */
    public static Date now() {
        return (new Date());
    }

    /**
     * 根据指定的格式格式化的当前时间
     *
     * @param formatStr
     * @return
     */
    public static String formatNow(String formatStr) {
        return (formatDate(now(), formatStr));
    }

    /**
     * 获取当前时间的Long（时间戳）
     *
     * @return
     */
    public static Long getCurrentTime() {
        return getTime(now());
    }


    /**
     * 获取指定日期的long型时间数据（时间戳）
     *
     * @param date
     * @return
     */
    public static Long getTime(Date date) {
        if (null == date) {
            return null;
        }
        return date.getTime();
    }

    /**
     * 格式化指定的日期
     *
     * @param date
     * @param formatStr
     * @return
     */
    public static String dateFormat(Date date, String formatStr) {
        return (formatDate(date, formatStr));
    }

    /**
     * 格式化日期
     *
     * @param date，待格式化日期
     * @param pattern，格式化规则，默认为"yyyy-MM-dd"
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        String patternStr = pattern;
        if (patternStr == null) {
            patternStr = "yyyy-MM-dd";
        }
        return longToString(date.getTime(), patternStr);
    }

    /**
     * 将字符串格式时间转化为日期格式（默认：yyyy-MM-dd）
     *
     * @param str
     * @return
     * @throws ParseException
     */
    public static Date getDateFromStr(String str) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(YYYY_MM_dd);
        try {
            return simpleDateFormat.parse(str);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 将字符串格式时间转化为指定的日期格式
     *
     * @param str
     * @return
     * @throws ParseException
     */
    public static Date getDateFromStr(String str, String formatStr) {
        String[] formats = {formatStr};
        if (StringUtils.isBlank(formatStr)) {
            formats = new String[]{
                    YYYY_MM_dd_HHmmss
                    , YYYY_MM_dd_HHmm
                    , YYYY_MM_dd_HH
                    , YYYY_MM_dd
                    , YYYYMMddHHmmss
                    , YYYYMMddHHmm
                    , YYYYMMddHH
                    , YYYYMMdd
                    , YYYY$MM$ddHHmmss
                    , YYYY$MM$ddHHmm
                    , YYYY$MM$ddHH
                    , YYYY$MM$dd};
        }
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str, formats);
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取两个日期的相差天数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int getDaysBetween(Date d1, Date d2) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d1);
        long time1 = calendar.getTimeInMillis();
        calendar.setTime(d2);
        long time2 = calendar.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取两个日期的相差天数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int getHoursBetween(Date d1, Date d2) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d1);
        long time1 = calendar.getTimeInMillis();
        calendar.setTime(d2);
        long time2 = calendar.getTimeInMillis();
        long between_hours = (time2 - time1) / (1000 * 3600 * 1);
        return Integer.parseInt(String.valueOf(between_hours));
    }


    /**
     * 根据指定的日期获取毫秒数
     *
     * @param time
     * @return
     */
    public static Long getLongByDateBeginTime(String time) {
        return getLongByDate(time, YYYY_MM_dd_HHmmss);
    }

    /**
     * 根据指定的日期获取毫秒数
     *
     * @param time
     * @return
     */
    public static Long getLongByDate(String time, String format) {
        Date date = getDateFromStr(time, format);
        return getTime(date);
    }


    /**
     * 获取今天的00:00:00
     *
     * @return
     */
    public static String getTodayBeginTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取昨天的00:00:00
     *
     * @return
     */
    public static String getYesterdayBeginTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day - 1);
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取前天的00:00:00
     *
     * @return
     */
    public static String getTwoDaysAgoBeginTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day - 2);
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取前n天的00:00:00
     *
     * @return
     */
    public static String getNAgoBeginTime(int n) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day - n);
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取指定时间前n天的00:00:00
     *
     * @return
     */
    public static String getNAgoByTheDate(Date dateTime, int n) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        cal.setTime(dateTime);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day - n);
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取明天的00:00:00
     *
     * @return
     */
    public static String getTomorrowBeginTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day + 1);
        String date = format.format(cal.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取今天的00:00:00
     *
     * @return
     */
    public static Date getTodayBeginDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        String date = format.format(cal.getTime());
        return getDateFromStr(date, YYYY_MM_dd);
    }

    /**
     * 获取昨天的00:00:00
     *
     * @return
     */
    public static Date getYesterdayBeginDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day - 1);
        String date = format.format(cal.getTime());
        return getDateFromStr(date, YYYY_MM_dd);
    }

    /**
     * 获取明天的00:00:00
     *
     * @return
     */
    public static Date getTomorrowBeginDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, day + 1);
        String date = format.format(cal.getTime());
        return getDateFromStr(date, YYYY_MM_dd);
    }


    /**
     * 获取当月1号的0点0时0分的时间
     *
     * @return
     */
    public static Date getMonthFirstDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        cal.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        String date = format.format(cal.getTime());
        return getDateFromStr(date);
    }

    public static String getMonthFirstDay() {
        return formatDate(getMonthFirstDate(), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取上个月1号的0点0时0分的时间
     *
     * @return
     */
    public static Date getPreMonthFirstDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();//获取当前日期
        int month = cal.get(Calendar.MONTH);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        String date = format.format(cal.getTime());
        return getDateFromStr(date);
    }

    public static String getPreMothFirstDay() {
        return formatDate(getPreMonthFirstDate(), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取下个月1号的0点0时0分的时间
     *
     * @return
     */

    public static String getNextMonthFirstDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 1);
        String date = format.format(calendar.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取当前周的第n天的00:00:00
     * 周日：n=1,  周一：n=2...
     *
     * @return
     */
    public static Date getDateOfWeek(int n) {
        LocalDate today = LocalDate.now();
        TemporalField fieldISO = WeekFields.of(Locale.CHINA).dayOfWeek();
        LocalDate firstDayOfThisWeek = today.with(fieldISO, n);
        return Date.from(firstDayOfThisWeek.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }


    /**
     * 获取在当前时间之前 最近的一个周n的 00:00:00
     * 周日：n=1, 周一：n=2...
     */
    public static Date getLatestDateOfWeek(int n) {
        Date latestDateOfWeek = getDateOfWeek(n);
        Date now = now();
        if (latestDateOfWeek.getTime() > now.getTime()) {
            String latestDateStr = getNAgoByTheDate(latestDateOfWeek, 7);
            latestDateOfWeek = getDateFromStr(latestDateStr, YYYY_MM_dd_HHmmss);
        }
        return latestDateOfWeek;
    }


    /**
     * 获取指定时间的23:59:59
     *
     * @param date
     * @return
     */
    public static Date getAppointDateEndTime(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.HOUR_OF_DAY, 23);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        dateEnd.set(Calendar.MILLISECOND, 999);
        String finalDate = format.format(dateEnd.getTime());
        return getDateFromStr(finalDate, YYYY_MM_dd_HHmmss);
    }

    /**
     * 获取指定时间的00:00:00
     */
    public static Long getAppointDateBeginTime(Long time) {
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTimeInMillis(time);
        dateEnd.set(Calendar.HOUR_OF_DAY, 0);
        dateEnd.set(Calendar.MINUTE, 0);
        dateEnd.set(Calendar.SECOND, 0);
        dateEnd.set(Calendar.MILLISECOND, 0);
        return dateEnd.getTimeInMillis();
    }

    /**
     * 根据指定的日期的字符串以及时间格式，获得该日期指定月份1号的日期 (00:00:00)
     *
     * @param dateStr
     * @param index     0 代表当月；n代表：下n个月；-n代表：上n个月
     * @param formatStr
     * @return
     */
    public static String getMonthFirstDateByMonth(String dateStr, int index, String formatStr) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        //设置时间
        calendar.setTime(getDateFromStr(dateStr, formatStr));
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, index);
        String date = format.format(calendar.getTime());
        return formatDate(getDateFromStr(date), YYYY_MM_dd_HHmmss);
    }

    /**
     * 根据日期获取星期几
     *
     * @param date
     * @return
     */
    public static String getWeekDayByDate(Date date) {
        String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (index < 0) {
            index = 0;
        }
        return weeks[index];
    }

    /**
     * 根据日期获取星期几(返回的是int 0是周天 1是周一 ，以此类推，0-6循环)
     *
     * @param date
     * @return
     */
    public static int getWeekDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 将长整型数字转换为日期格式的字符串
     *
     * @param time
     * @param format
     * @return
     */
    public static String longToDateStr(long time, String format) {
        if (time > 0l) {
            if (StringUtils.isBlank(format)) {
                format = YYYY_MM_dd_HHmmss;
            }
            SimpleDateFormat sf = new SimpleDateFormat(format);
            Date date = new Date(time);
            return sf.format(date);
        }
        return "";
    }

    public static String longToString(long time, String format) {
        TimeZone tz = TimeZone.getTimeZone("GMT+8");
        if (format == null) {
            format = "yyyyMMdd HH:mm:ss";
        }
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(time);

        return DateFormatUtils.format(c, format, tz, Locale.US);
    }


    /**
     * 时间周期工具：将一天划分为间隔为period分钟的时间周期，并根据delay和curTime获取 开始时间和结束时间的List
     *
     * @param time       时间值
     * @param delay      向前时延周期倍数
     * @param difference StartTime和EndTime时间差周期倍数
     * @param period     周期长度, 单位(分钟)
     * @return 开始时间和结束时间的list
     */
    public static List<Long> getTimePeriodList(long time, int delay, int difference, int period) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(time);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        List<Long> list = Lists.newArrayList();
        Long endTIme = c.getTimeInMillis() - delay * period * 60 * 1000;
        Long startTime = endTIme - difference * period * 60 * 1000;
        list.add(startTime);
        list.add(endTIme);
        return list;
    }

    /**
     * 获取指定时间的N:00:00
     *
     * @param date
     * @return
     */
    public static String getAppointDateHourBingTime(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_dd_HHmmss);
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.MINUTE, 0);
        dateEnd.set(Calendar.SECOND, 0);
        dateEnd.set(Calendar.MILLISECOND, 0);
        String finalDate = format.format(dateEnd.getTime());
        return finalDate;
    }

    /**
     * 获取指定时间的N:59:59
     *
     * @param date
     * @return
     */
    public static String getAppointDateHourEndTime(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_dd_HHmmss);
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.MINUTE, 59);
        dateEnd.set(Calendar.SECOND, 59);
        dateEnd.set(Calendar.MILLISECOND, 999);
        String finalDate = format.format(dateEnd.getTime());
        return finalDate;
    }

    /**
     * 获取指定时间的N:00:00
     *
     * @param date
     * @return
     */
    public static String getAppointDayBingTime(Date date) {
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_dd);
        Calendar dateEnd = Calendar.getInstance();
        dateEnd.setTime(date);
        dateEnd.set(Calendar.HOUR_OF_DAY, 0);
        dateEnd.set(Calendar.MINUTE, 0);
        dateEnd.set(Calendar.SECOND, 0);
        dateEnd.set(Calendar.MILLISECOND, 0);
        String finalDate = format.format(dateEnd.getTime());
        return finalDate;
    }

    /**
     * 将时间戳转为UTC时间
     */
    public static Date millisTime2UTCTime(Long millis) {
        try {
            Calendar cal = Calendar.getInstance();
            int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
            int dstOffset = cal.get(Calendar.DST_OFFSET);
            cal.setTimeInMillis(millis);
            SimpleDateFormat foo = new SimpleDateFormat(YYYY_MM_dd_HHmmss);
            cal.add(Calendar.MILLISECOND, (zoneOffset + dstOffset));
            String time = foo.format(cal.getTime());
            return foo.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取本月第一天零点时刻日期
     *
     * @return
     */
    public static Date getFirstDayAndTimeOfCurrentMonth() {
        return getFirstDayAndTimeOfMonth(Calendar.getInstance().getTime());
    }

    /**
     * 获取某个月第一天零点时刻日期
     *
     * @param date
     * @return
     */
    public static Date getFirstDayAndTimeOfMonth(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }

        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return getFirstTimeOfDate(calendar.getTime());
    }


    /**
     * 获取本月最后一天最后时刻日期
     *
     * @return
     */
    public static Date getLastDayAndTimeOfCurrentMonth() {
        return getLastDayAndTimeOfMonth(Calendar.getInstance().getTime());
    }

    /**
     * 获取某月最后一天最后时刻的日期
     *
     * @param date
     * @return
     */
    public static Date getLastDayAndTimeOfMonth(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));

        return getLastTimeOfDate(calendar.getTime());
    }

    /**
     * 获取今天00:00:00时刻日期
     *
     * @return
     */
    public static Date getFirstTimeOfToday() {
        return getFirstTimeOfDate(Calendar.getInstance().getTime());
    }

    /**
     * 获取某天00:00:00时刻日期
     *
     * @param date
     * @return
     */
    public static Date getFirstTimeOfDate(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取今天23：59：59秒日期
     *
     * @return
     */
    public static Date getLastTimeOfToday() {
        return getLastTimeOfDate(Calendar.getInstance().getTime());
    }

    /**
     * 获某天23：59：59秒日期
     *
     * @param date
     * @return
     */
    public static Date getLastTimeOfDate(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
        return calendar.getTime();
    }

    /**
     * 获取今年年份
     *
     * @return
     */
    public static int getCurrentYear() {
        return getYear(Calendar.getInstance().getTime());
    }

    /**
     * 获取本月月份,返回1-12
     *
     * @return
     */
    public static int getCurrentMonth() {
        return getMonth(Calendar.getInstance().getTime());
    }

    /**
     * 获取本月的天数
     *
     * @return
     */
    public static int getCurrentDay() {
        return getDay(Calendar.getInstance().getTime());
    }

    /**
     * 获取某个日期的年份
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取某个日期的月份，返回1-12
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取某个日期的天数
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        if (date == null) {
            throw new InvalidParameterException("date cannot be null!");
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }
}
